import errorCodesBuilder from '../../helpers/errorCodesBuilder';
import { VUL_LEVEL_MAP } from '../../../common/constants';
import { warnEventId, warnIdSplit } from '../../../common/warnId';
import request from './monitorTaskRequest';

const errorCodes = errorCodesBuilder();
const speedMap = {
	high: 'quick',
	medium: 'normal',
	low: 'deep',
};

export function resultParser({ statistics, info, results }) {
	return {
		addition: { statistics, info },
		warnings: results.map(x => ({
			id: warnEventId({ taskType: 'vul', id: x.name, affects: x.affects }),
			level: VUL_LEVEL_MAP[x.risk] || 1,
			title: x.display_name,
			category: x.category,
			affects: x.affects,
			detailText: x.detail,
			detail: x,
		})),
	};
}

export default (config, server) =>
	async function vul(job) {
		const api = config.api;

		const payload = { url: job.data.target };
		const { collect, isSpecialTask } = job.data;
		if (isSpecialTask) {
			const plugins = warnIdSplit(collect.vul).id;
			payload.plugins = plugins;
		} else {
			if (collect.speed) {
				payload.scan_mode = speedMap[collect.speed] || 'normal';
			}
			if (collect.depth) {
				payload.spider_depth = collect.depth;
			}
			if (collect.maxPage) {
				payload.spider_max_page = collect.maxPage;
			}
			if (collect.includeUrls) {
				payload.include_urls = collect.includeUrls
					.map(x => encodeURI(decodeURI(x.trim())))
					.join('\n');
			}
			if (collect.type === 'increment') {
				payload.deltascan = true;
				payload.scan_mode = 'normal';
				payload.spider_depth = 10;
			}
		}

		let result;
		try {
			result = await request({
				job,
				payload,
				api,
				checkInterval: config.checkInterval,
			});
		} catch (err) {
			const error = errorCodes['[05]漏洞扫描: 漏洞扫描任务创建失败'].from(err);
			server.log.error(
				{
					error,
					job,
					payload,
					api,
					checkInterval: config.checkInterval,
				},
				error.rawMessage
			);
			throw error;
		}

		if (!result?.results) {
			server.log.warn({ result, api, job: job.data }, '漏洞扫描结果为空');
		}

		return resultParser(result);
	};
